﻿using System.Collections.Generic;
using System.ComponentModel.Composition;
using Roslyn.Compilers.Common;
using Roslyn.Compilers.CSharp;
using RoslynCompiler.MEF;

namespace ParameterizedNewGenericConstraint
{
    [Export(typeof(ICodeRewriter))]
    public class ParameterizedNewGenericConstraintCodeRewriter : ICodeRewriter
    {
        private Dictionary<ClassDeclarationSyntax, Dictionary<string, List<TypeConstraintSyntax>>> classesWithFactory = new Dictionary<ClassDeclarationSyntax, Dictionary<string, List<TypeConstraintSyntax>>>();

        public SyntaxNode Rewrite(SyntaxNode originalNode, int rewriterIndex, ISemanticModel semanticModel)
        {
            switch (rewriterIndex)
            {
                case 0:
                    List<ParameterizedNewGenericConstraintAnnotation> parameterizedNewGenericConstraintAnnotation = new List<ParameterizedNewGenericConstraintAnnotation>();
                    var value = new ClassParameterizedNewGenericConstraintRewriter(semanticModel, parameterizedNewGenericConstraintAnnotation).Visit((SyntaxNode)originalNode);
                    foreach (var newGenericConstraintAnnotation in parameterizedNewGenericConstraintAnnotation)
                        foreach (ClassDeclarationSyntax classWithFactory in value.GetAnnotatedNodesAndTokens(newGenericConstraintAnnotation))
                            classesWithFactory.Add(classWithFactory, newGenericConstraintAnnotation.TypesConstraintSyntax);
                    return value;
                case 1:
                    return new GenericClassInstanciationRewriter(semanticModel, classesWithFactory).Visit(originalNode);
            }
            return originalNode;
        }

        public int RewriterCount
        {
            get { return 2; }
        }
    }
}
